package org.ouwh.oowiki.ctrl;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

import org.ouwh.fw.model.data.Struct;
import org.ouwh.fw.util.xml.Node;
import org.ouwh.oowiki.GlobalConstants;
import org.ouwh.oowiki.http.MyException;
import org.ouwh.oowiki.http.MyRequest;
import org.ouwh.oowiki.http.MyResponse;

public abstract class BaseController extends AbstractController {
	protected MyResponse response = new MyResponse();
	
	protected Struct user;
	protected String actionName;
	
	@Override
	public void init(Node node) throws Exception {
		super.init(node);
		addBeforeInterceptor(new SessionCheckInterceptor());
	};

	private class SessionCheckInterceptor implements IBeforeControllerInterceptor {
		@Override
		public void beforeController(MyRequest request) throws MyException {
			response.putResult("__actionName", actionName);
			response.putResult("__navName", controllerName);
			response.putResult("__version", GlobalConstants.VERSION);
			response.putResult("__copyright", GlobalConstants.COPY_RIGHT);

			if (controllerName.equals("author")) {
				return;
			}
			if (!isLogin()) {
				throw new MyException(ErrorCodes.UN_AUTHENTICATE);
			}
			if (!checkAccess()) {
				throw new MyException(ErrorCodes.NO_PERMISSION);
			}
		}
		@Override
		public String getControllerName() {
			return controllerName;
		}
		@Override
		public void setControllerName(String controllerName) {
		}
	}
	
	private boolean isLogin() {
		if (controllerName.equals("page") && actionName.equals("display")) {
			return true;
		}
		Cookie[] cookies = rawRequest.getCookies();
		if (cookies == null) {
			return false;
		}
		String sessionId = null;
		String userName = null;
		for (Cookie cookie : cookies) {
			if (cookie.getName().equals("session-id")) {
				sessionId = cookie.getValue();
			} else if (cookie.getName().equals("username")) {
				userName = cookie.getValue();
			}
		}
		if (userName == null || sessionId == null) {
			return false;
		}
		try {
			user = getSession(sessionId);
			if ((user == null) || (!userName.equals(user.getValueAt("username")))) {
				return false;
			}
		} catch (Exception e) {
			return false;
		}
		return true;
	}

	private Struct getSession(String sessionId) {
		// TODO Auto-generated method stub
		return null;
	}

	// check access
	protected boolean checkAccess() {
		/*path := this.Ctx.Request.URL.Path
		mca := strings.Split(strings.Trim(path, "/"), "/")

		// must /system/controller/action
		if (len(mca) >= 3) && (strings.ToLower(mca[0]) == "system") {
			this.Data["navName"] = "system"
			// no check '/system/main/index' '/system/main/default'
			if (this.controllerName == "main" && this.actionName == "index") || this.controllerName == "main" && this.actionName == "default" {
				return true
			}
			if this.IsRoot() {
				return true
			}
			_, controllers, err := models.PrivilegeModel.GetTypePrivilegesByUserId(this.UserId)
			if err != nil {
				this.ErrorLog("获取用户 " + this.UserId + " 权限失败：" + err.Error())
				return false
			}
			for _, controller := range controllers {
				action := strings.ToLower(controller["action"])
				controller := strings.ToLower(controller["controller"])
				if this.controllerName == controller && this.actionName == action {
					return true
				}
			}
			return false
		}*/
		return true;
	}

	// view layout
	protected void viewLayout(String viewName, String layout) {
		response.putResult("__layout", layout + ".html");
		response.putResult("__viewName", viewName + ".html");
		response.putResult("__title", "OO-Wiki");
		response.putResult("__copyright", GlobalConstants.COPY_RIGHT);
	}

	// view layout
	protected void viewError(Struct message, Struct data) {
		/*this.Layout = "error/default.html"
		this.TplName = "layouts/default.html"
		var url = ""
		var sleep = "5"
		if len(redirect) == 1 {
			url = redirect[0]
		}
		if len(redirect) > 1 {
			sleep = redirect[1]
		}
		if content == "" {
			content = "操作失败"
		}
		this.Data["content"] = content
		this.Data["url"] = url
		this.Data["sleep"] = sleep
		this.Data["copyright"] = app.CopyRight
		this.Render()*/
	}

	// return json success
	protected void jsonSuccess(Struct message, Struct data) {
		/*url := ""
		sleep := 2000
		var _data interface{}
		if len(data) > 0 {
			_data = data[0]
		}
		if len(data) > 1 {
			url = data[1].(string)
		}
		if len(data) > 2 {
			sleep = data[2].(int)
		}
		this.Data["json"] = JsonResponse{
			Code:    1,
			Message: message,
			Data:    _data,
			Redirect: map[string]interface{}{
				"url":   url,
				"sleep": sleep,
			},
		}

		j, err := json.MarshalIndent(this.Data["json"], "", "\t")
		if err != nil {
			this.Abort(err.Error())
		} else {
			this.Ctx.Output.Header("Content-Type", "application/json; charset=utf-8")
			this.Abort(string(j))
		}*/
	}

	// return json error
	protected void jsonError(Struct message, Struct data) {
		/*url := ""
		sleep := 2000
		var _data interface{}
		if len(data) > 0 {
			_data = data[0]
		}
		if len(data) > 1 {
			url = data[1].(string)
		}
		if len(data) > 2 {
			sleep = data[2].(int)
		}
		this.Data["json"] = JsonResponse{
			Code:    0,
			Message: message,
			Data:    _data,
			Redirect: map[string]interface{}{
				"url":   url,
				"sleep": sleep,
			},
		}
		j, err := json.MarshalIndent(this.Data["json"], "", " \t")
		if err != nil {
			this.Abort(err.Error())
		} else {
			this.Ctx.Output.Header("Content-Type", "application/json; charset=utf-8")
			this.Abort(string(j))
		}*/
	}

	// get client ip
	protected String getClientIp() {
		return rawRequest.getRemoteAddr();
	}

	// paginator
	protected void setPaginator(int per, long nums) {
		/*p := utils.NewPaginator(this.Ctx.Request, per, nums)
		this.Data["paginator"] = p
		return p*/
	}

	// is Post
	protected boolean isPost() {
		return rawRequest.getMethod().equals("POST");
	}

	// is Get
	protected boolean isGet() {
		return rawRequest.getMethod().equals("GET");
	}

	// 是否是超级管理员
	protected boolean isRoot() {
		//return this.User["role_id"] == fmt.Sprintf("%d", models.Role_Root_Id)
		return false;
	}

	/*func (this *TemplateController) GetRangeInt(key string, def int, min int, max int) (n int, err error) {
		n, err = this.GetInt(key, def)
		if err != nil {
			return
		}
		if n < min {
			n = min
		}
		if n > max {
			n = max
		}
		return n, nil
	}*/

	protected int getDocumentPrivilege(Struct space) {
		/*
		if this.IsRoot() {
			return true, true, true
		}
		spaceUser, _ := models.SpaceUserModel.GetSpaceUserBySpaceIdAndUserId(space["space_id"], this.UserId)
		if len(spaceUser) == 0 {
			if space["visit_level"] == models.Space_VisitLevel_Private {
				return false, false, false
			} else {
				return true, false, false
			}
		}
		if spaceUser["privilege"] == fmt.Sprintf("%d", models.SpaceUser_Privilege_Editor) {
			return true, true, false
		}
		if spaceUser["privilege"] == fmt.Sprintf("%d", models.SpaceUser_Privilege_Manager) {
			return true, true, true
		}
		return true, false, false*/
		return 0;
	}

	protected void logRecord(String msg, int level) {
		/*userAgent := this.Ctx.Request.UserAgent()
		referer := this.Ctx.Request.Referer()
		getParams := this.Ctx.Request.URL.String()
		path := this.Ctx.Request.URL.Path
		this.Ctx.Request.ParseForm()
		postParamsMap := map[string][]string(this.Ctx.Request.PostForm)
		postParams, _ := json.Marshal(postParamsMap)
		user := this.GetSession("author").(map[string]string)

		logValue := map[string]interface{}{
			"level":       level,
			"path":        path,
			"get":         getParams,
			"post":        string(postParams),
			"message":     message,
			"ip":          this.GetClientIp(),
			"user_agent":  userAgent,
			"referer":     referer,
			"user_id":     user["user_id"],
			"username":    user["username"],
			"create_time": time.Now().Unix(),
		}

		models.LogModel.Insert(logValue)*/
	}


	protected Struct getLogValue(MyRequest request) {
		HttpServletRequest raw = request.getRawRequest();
		String userAgent = raw.getHeader("User Agent");
		String referer = raw.getHeader("Referer");
		String params = raw.getRequestURI();
		String path = raw.getRequestURI();
		/*this.Ctx.Request.ParseForm()
		postParamsMap := map[string][]string(this.Ctx.Request.PostForm)
		postParams, _ := json.Marshal(postParamsMap)
		user := this.GetSession("author").(map[string]string)
		logValue := map[string]interface{}{
			"level":       models.Log_Level_Info,
			"path":        path,
			"get":         getParams,
			"post":        string(postParams),
			"message":     "",
			"ip":          this.GetClientIp(),
			"user_agent":  userAgent,
			"referer":     referer,
			"user_id":     user["user_id"],
			"username":    user["username"],
			"create_time": time.Now().Unix(),
		}*/
		return null;
	}
}
